package com.cn.onetrip.activity;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.app.Activity;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.MKGeneralListener;
import com.baidu.mapapi.cloud.Bounds;
import com.baidu.mapapi.map.ItemizedOverlay;
import com.baidu.mapapi.map.LocationData;
import com.baidu.mapapi.map.MKEvent;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationOverlay;
import com.baidu.mapapi.map.OverlayItem;
import com.baidu.mapapi.map.PopupClickListener;
import com.baidu.mapapi.map.PopupOverlay;
import com.baidu.mapapi.search.MKAddrInfo;
import com.baidu.mapapi.search.MKRoutePlan;
import com.baidu.mapapi.search.MKSearch;
import com.baidu.mapapi.utils.DistanceUtil;
import com.baidu.platform.comapi.basestruct.GeoPoint;
import com.cn.onetrip.objects.LarkObj;
import com.cn.onetrip.objects.RouteObj;
import com.cn.onetrip.objects.RoutePointObj;
import com.cn.onetrip.activity.R;
import com.cn.onetrip.untility.ImageUtils;
import com.cn.onetrip.untility.NetworkManager;
import com.cn.onetrip.untility.SysApplication;

public class ScenicMapLocationActivity extends Activity {

	public static final int ROUTE_POINT_LOCATION = 0;
	public static final int STORE_LOCATION = 1;

	private LocationMapView mMapView = null;
	private BMapManager mapManager = null;
	private LocationOverlay myLocationOverlay = null;
	private MapController mMapController;
	private AddressOverlay mOverlay;
	private OverlayItem mCurItem;
	private PopupOverlay popupOverlay;

	private LocationClient mLocClient;
	private LocationData locData = null;

	private TextView textView;
	private TextView myLocationTextView = null;
	private PopupOverlay myLocationPop = null;

	private boolean isFirstLoc = true;
	private boolean isLocationClientStop = false;

	// private RouteObj routeObj = null;
	private LarkObj larkObj = null;
	private int type = ROUTE_POINT_LOCATION;

	private String address = "";
	private String myAddress = "";

	private MyLocationListenner myListener = new MyLocationListenner();
	private String apiKey = "E825493E52D16575EE7E44C235D17BF6ED7B04DB";

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (SysApplication.routesList.size() == 0) {
			finish();
			android.os.Process.killProcess(android.os.Process.myPid());
		}
		initEngineManager();

		setContentView(R.layout.activity_scenic_map_location);

		int index = getIntent().getIntExtra("index", 0);
		type = getIntent().getIntExtra("location_type", 0);
		if (type == STORE_LOCATION) {
			larkObj = SysApplication.larkList.get(index);
		} else {
			// routeObj = SysApplication.routesList.get(index);
		}

		// initialize MapView
		mMapView = (LocationMapView) findViewById(R.id.scenicMapView);
		mMapController = mMapView.getController();
		mMapView.getController().enableClick(true);
		mMapView.setBuiltInZoomControls(true);
		mMapController.setZoom(14);

		createPop();

		// initialize location
		mLocClient = new LocationClient(this);
		mLocClient.registerLocationListener(myListener);
		LocationClientOption option = new LocationClientOption();
		option.setOpenGps(true);
		option.setAddrType("all");
		option.setCoorType("bd09ll"); // set the type of coordinate
		option.setScanSpan(5000);
		mLocClient.setLocOption(option);
		mLocClient.start();

		locData = new LocationData();
		myLocationOverlay = new LocationOverlay(mMapView);
		myLocationOverlay.setData(locData);
		mMapView.getOverlays().add(myLocationOverlay);
		myLocationOverlay.enableCompass();
		mMapView.refresh();

		initOverlay();

		((ImageButton) findViewById(R.id.baidu_map_return))
				.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						returnClick();
					}
				});
	}

	private void createPop() {
		myLocationTextView = new TextView(this);
		myLocationTextView.setTextColor(Color.WHITE);
		myLocationTextView.setBackgroundResource(R.drawable.map_pop);
		myLocationTextView.setLayoutParams(new LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

		PopupClickListener popListener = new PopupClickListener() {
			@Override
			public void onClickedPopup(int index) {
				Log.v("click", "clickapoapo");
			}
		};
		myLocationPop = new PopupOverlay(mMapView, popListener);
		LocationMapView.pop = myLocationPop;
	}

	private void initOverlay() {

		mOverlay = new AddressOverlay(null, mMapView);

		if (type == STORE_LOCATION) {
			GeoPoint p = new GeoPoint((int) (larkObj.latitude * 1E6),
					(int) (larkObj.longitude * 1E6));
			mMapController.setCenter(p);
			OverlayItem item = new OverlayItem(p, larkObj.address, "");
			item.setMarker(getResources().getDrawable(
					R.drawable.map_destination_location));
			mOverlay.addItem(item);

		} else {
			// for (RoutePointObj pointObj : routeObj.pointList) {
			// GeoPoint p = new GeoPoint((int) (pointObj.latitude * 1E6),
			// (int) (pointObj.longitude * 1E6));
			// OverlayItem item = new OverlayItem(p, pointObj.name, "");
			// int drawableID = getResources().getIdentifier(
			// "pop" + (pointObj.index + 1), "drawable",
			// getPackageName());
			// item.setMarker(getResources().getDrawable(drawableID));
			// mOverlay.addItem(item);
			// }
		}

		mMapView.getOverlays().add(mOverlay);
		mMapView.refresh();

		textView = new TextView(this);
		textView.setTextColor(Color.WHITE);
		textView.setGravity(Gravity.CENTER);
		textView.setBackgroundResource(R.drawable.map_pop);
		textView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT));

		PopupClickListener popListener = new PopupClickListener() {
			@Override
			public void onClickedPopup(int index) {

				popupOverlay.hidePop();
				GeoPoint p = new GeoPoint(
						mCurItem.getPoint().getLatitudeE6() + 5000, mCurItem
								.getPoint().getLongitudeE6() + 5000);
				mCurItem.setGeoPoint(p);
				mOverlay.updateItem(mCurItem);
				mMapView.refresh();

			}
		};
		popupOverlay = new PopupOverlay(mMapView, popListener);
	}

	/**
	 * location SDK listener
	 */
	public class MyLocationListenner implements BDLocationListener {

		@Override
		public void onReceiveLocation(BDLocation location) {
			if (location == null || isLocationClientStop)
				return;
			locData.latitude = location.getLatitude();
			locData.longitude = location.getLongitude();
			locData.accuracy = location.getRadius();
			locData.direction = location.getDerect();

			myLocationOverlay.setData(locData);
			mMapView.refresh();

			if (location.getLocType() == BDLocation.TypeNetWorkLocation)
				myAddress = location.getAddrStr();

			if (isFirstLoc) {

				int nwLat = (int) (locData.latitude * 1E6);
				int nwLng = (int) (locData.longitude * 1E6);
				int seLat = (int) (locData.latitude * 1E6);
				int seLng = (int) (locData.longitude * 1E6);

				// find bounding lats and lngs
				if (type == STORE_LOCATION) {
					nwLat = Math.max(nwLat, (int) (larkObj.latitude * 1E6));
					nwLng = Math.min(nwLng, (int) (larkObj.longitude * 1E6));
					seLat = Math.min(seLat, (int) (larkObj.latitude * 1E6));
					seLng = Math.max(seLng, (int) (larkObj.longitude * 1E6));
				} else {
					// for (RoutePointObj pointObj : routeObj.pointList) {
					// nwLat = Math
					// .max(nwLat, (int) (pointObj.latitude * 1E6));
					// nwLng = Math.min(nwLng,
					// (int) (pointObj.longitude * 1E6));
					// seLat = Math
					// .min(seLat, (int) (pointObj.latitude * 1E6));
					// seLng = Math.max(seLng,
					// (int) (pointObj.longitude * 1E6));
					// }
				}

				GeoPoint center = new GeoPoint((nwLat + seLat) / 2,
						(nwLng + seLng) / 2);

				// add padding in each direction
				int spanLatDelta = (int) (Math.abs(nwLat - seLat) * 2);
				int spanLngDelta = (int) (Math.abs(seLng - nwLng) * 2);

				// fit map to points
				mMapController.zoomToSpan(spanLatDelta, spanLngDelta);
				mMapController.animateTo(center);

			}
			isFirstLoc = false;
		}

		public void onReceivePoi(BDLocation poiLocation) {
			if (poiLocation == null) {
				return;
			}
		}
	}

	public void clearOverlay() {
		mOverlay.removeAll();
		if (popupOverlay != null) {
			popupOverlay.hidePop();
			popupOverlay = null;
		}
		mMapView.refresh();
	}

	@Override
	protected void onPause() {
		isLocationClientStop = true;
		mLocClient.stop();
		mMapView.onPause();

		super.onPause();
	}

	@Override
	protected void onResume() {
		isLocationClientStop = false;
		mMapView.onResume();
		super.onResume();
	}

	@Override
	protected void onDestroy() {
		clearOverlay();

		mMapView.destroy();
		mLocClient.unRegisterLocationListener(myListener);

		if (mapManager != null) {
			mapManager.destroy();
			mapManager = null;
		}

		mLocClient.stop();
		myLocationOverlay.disableCompass();
		myLocationOverlay = null;
		mMapView = null;
		mLocClient = null;
		locData = null;

		super.onDestroy();
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {

			returnClick();
		}
		return super.onKeyDown(keyCode, event);
	}

	private void returnClick() {
		finish();
		overridePendingTransition(R.anim.push_left_translate,
				R.anim.pull_right_translate);
		System.gc();
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		mMapView.onSaveInstanceState(outState);

	}

	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);
		mMapView.onRestoreInstanceState(savedInstanceState);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

	public void initEngineManager() {
		if (mapManager == null) {
			mapManager = new BMapManager(getApplication());
		}

		boolean initResult = mapManager.init(apiKey, new MKGeneralListener() {

			@Override
			public void onGetNetworkState(int iError) {
				if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
					NetworkManager.NetworkTips(ScenicMapLocationActivity.this);
				} else if (iError == MKEvent.ERROR_NETWORK_DATA) {
					Toast.makeText(
							ScenicMapLocationActivity.this,
							getResources().getString(
									R.string.baidu_map_data_error),
							Toast.LENGTH_LONG).show();
				}
			}

			@Override
			public void onGetPermissionState(int iError) {

			}
		});

		if (!initResult) {
			Toast.makeText(ScenicMapLocationActivity.this,
					getResources().getString(R.string.baidu_map_init_fail),
					Toast.LENGTH_LONG).show();
		}
	}

	public class AddressOverlay extends ItemizedOverlay<OverlayItem> {

		public AddressOverlay(Drawable defaultMarker, MapView mapView) {
			super(defaultMarker, mapView);
		}

		@Override
		public boolean onTap(int index) {
			mCurItem = getItem(index);

			textView.setText(getItem(index).getTitle());
			Drawable drawable = getResources().getDrawable(R.drawable.pop1);

			popupOverlay.showPopup(ImageUtils.getBitmapFromView(textView),
					getItem(index).getPoint(),
					drawable.getIntrinsicHeight() / 2);

			return true;
		}

		@Override
		public boolean onTap(GeoPoint pt, MapView mMapView) {
			if (popupOverlay != null) {
				popupOverlay.hidePop();
			}
			return false;
		}
	}

	public class LocationOverlay extends MyLocationOverlay {

		public LocationOverlay(MapView mapView) {
			super(mapView);
		}

		@Override
		protected boolean dispatchTap() {

			if (myAddress == null || myAddress.equals(""))
				myLocationTextView.setText(getResources().getString(
						R.string.map_my_location));
			else
				myLocationTextView.setText(getResources().getString(
						R.string.map_my_location)
						+ "\n" + myAddress);

			myLocationPop.showPopup(ImageUtils
					.getBitmapFromView(myLocationTextView), new GeoPoint(
					(int) (locData.latitude * 1e6),
					(int) (locData.longitude * 1e6)), 8);

			return true;
		}
	}
}

class LocationMapView extends MapView {
	static PopupOverlay pop = null;

	public LocationMapView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public LocationMapView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public LocationMapView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (!super.onTouchEvent(event)) {
			// 消隐泡泡
			if (pop != null && event.getAction() == MotionEvent.ACTION_UP)
				pop.hidePop();
		}
		return true;
	}
}
